
import java.io.*;
import java.util.*;
import java.net.*;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;


public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws GameOverException
	{
		if(args.length < 1)
		{
		    System.out.println("Usage: java Client <IP address>");
			System.exit(0);
		}

		//String address = "127.0.0.1";
		String address = args[0];
		BufferedReader input_stream = null;
		PrintStream output_stream = null;
		Socket clientsock = null;
		ObjectInputStream serialize_in = null;

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in) );
		String sample;
		String ret_string = "";
		int num_treasures_left = 1;
		int individual_treasure = 0;
		int xpos, ypos;
		int thread_id;
		
		try
		{
			InetAddress ipAddress = InetAddress.getByName(address);
			
			clientsock = new Socket(ipAddress, 5555);
			input_stream = new BufferedReader(new InputStreamReader(clientsock.getInputStream()));
			output_stream = new PrintStream(clientsock.getOutputStream());
			serialize_in = new ObjectInputStream(clientsock.getInputStream());
		}
		catch (Exception ee)
		{
			System.out.println("Client::ERROR1" + ee);
		}
		try
		{
			String str = input_stream.readLine();
			long time_to_wait = Long.parseLong(str);
			System.out.println("Initializing...please wait for " + (time_to_wait/1000) + " seconds");
			Thread.sleep(time_to_wait);
			//this.wait(time_to_wait);
			System.out.println("GAME STARTED....PLAY");
		}
		catch(Exception e)
		{
		
			System.out.println("Client::ERROR2" + e);
		}
		while(true)
		{
			try
			{
				System.out.println("Enter the direction");
				sample = br.readLine();
				if(sample.compareTo("a") == 0)
					ret_string = "LEFT";
				else if(sample.compareTo("s") == 0)
					ret_string = "DOWN";
				else if(sample.compareTo("d") == 0)
					ret_string = "RIGHT";
				else if(sample.compareTo("w") == 0)
					ret_string = "UP";
				else 
					ret_string = "UPDATE_POS";
				output_stream.println(ret_string);
				System.out.println("String direction = " + ret_string);
			}
			
			catch (IOException ee)
			{
				System.out.println("Client::ERROR3" + ee);
			}
			
		    try
		    {
		    	thread_id = serialize_in.readInt();
		    	xpos = serialize_in.readInt();
		    	
		    	ypos = serialize_in.readInt();
		    	num_treasures_left = serialize_in.readInt();
		    	individual_treasure = serialize_in.readInt();
		    	
		    	LinkedList<Treasure> treasure_list = (LinkedList<Treasure>) serialize_in.readObject();
		    	Map<String, int[]> position_map = (Map<String, int[]>) serialize_in.readObject();
		    	
		    	System.out.println("========================================");
		    	System.out.println("|| YOUR POSITION (PLAYER " + thread_id + ")" + "-> " + "(" + xpos + " , " + ypos + ") " + "||");
		    	System.out.println("========================================");
				System.out.println("|| YOUR TREASURE COUNT = " + individual_treasure + "            ||");
				System.out.println("========================================");
				
				System.out.println("|| NUMBER OF REMAINING TREASURES = " + num_treasures_left + "  ||");
				System.out.println("========================================");
		    	
					
				//System.out.println("========================================");
				System.out.println("|| Treasures available at..." + "          ||");
				for(int z=0;z<treasure_list.size();z++)
				{
					System.out.println("||       " +  "(" + treasure_list.get(z).tr_xpos + " , " + treasure_list.get(z).tr_ypos + ")" + "                      ||");
				}
				System.out.println("========================================");
				Iterator iterator = position_map.keySet().iterator();
				while( iterator. hasNext() )
				{
					String str = (String)iterator.next();
					int[] a = position_map.get(str);
					
					System.out.println("|| Player " + str + " is at " + "(" + a[0] + " , " + a[1] + ")" + "             ||");
				}
				System.out.println("========================================");
				if (num_treasures_left == 0)
				{
				   	throw new GameOverException(num_treasures_left);
				}
		    }
		    catch(IOException io)
		    {
		    	System.out.println("GAME OVER");
				   
				System.out.println("YOUR TREASURE SCORE = " + individual_treasure);
				
				System.exit(0);
		    }
		    
		    catch(GameOverException go)
		    {
				System.out.println("All treasures found");
				System.out.println("YOUR TREASURE SCORE = " + individual_treasure);
				
				System.exit(0);
		    }
		    catch (Exception ee)
		    {
			    System.out.println("GAME OVER" + ee.getMessage());
			    System.out.println("YOUR TREASURE SCORE = " + individual_treasure);
				
			    System.exit(0);
		    }
		}
		/*try
		{
			input_stream.close();
			output_stream.close();
			clientsock.close();
		}
		catch (Exception ee)
		{
			System.out.println("Client::ERROR4");
				
		}*/
	}

}
class GameOverException extends Exception
{
	private int num_treasures;
	GameOverException(int x)
	{
		num_treasures = x;
	}
	public String toString() 
	{
		return "No more treasures";
	}
}
